//
//  LogOutPacketCenter.m
//  HiQServer
//
//  Created by shoguncao on 12-8-6.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "LogOutPacketCenter.h"
#import "MacroComd.h"
#import "MiniSocket.h"
#import "MainSocketDelegate.h"
#import "MysqlDB.h"

@implementation LogOutPacketCenter

- (void)MessageDispatch: (SockPacket *)packet
{
    ONOFFLINEHRD *hrd = (ONOFFLINEHRD *)[packet.packetContent bytes];
    
    if (hrd->operation == OP_STATUS_NOTIFY_OFFLINE)
    {
        MysqlDB *mysql = [[MysqlDB alloc] init];
        [mysql connectHost:hostIp connectUser:userName connectPassword:password connectName:dbName];
        // 查找该用户的所有好友，并向其发其所有在线好友发送上线提醒
        char *userIdChar = (char *)hrd + sizeof(ONOFFLINEHRD);
        NSData *userIdData = [[NSData alloc] initWithBytes:userIdChar length:hrd->userid_len];
        NSString *userIDStr = [NSKeyedUnarchiver unarchiveObjectWithData:userIdData];
        NSMutableString *sqlQueryForFriends = [[NSMutableString alloc] initWithFormat:@"SELECT * FROM tbFriends WHERE UserId = '"];
        [sqlQueryForFriends appendString:userIDStr];
        [sqlQueryForFriends appendString:@"'"];
        NSMutableArray *buddyList = [mysql doDataQuery:sqlQueryForFriends];
        for (NSInteger i=0; i<[buddyList count]; ++i)
        {
            NSMutableArray *buddy = [buddyList objectAtIndex:i];
            if ([buddy count] > COLUMN_OF_FRIENDID_IN_TBFRIENDS)   // 读出的数据有问题(比如数据表的字段修改了)
            {
                NSString *buddyIdStr = [buddy objectAtIndex:COLUMN_OF_FRIENDID_IN_TBFRIENDS];
                NSInteger buddyId = [buddyIdStr intValue];
                @synchronized([MainSocketDelegate connectedSocketsQueue])
                {
                    MiniSocket *_sock = [self isBuddyOnline:buddyId];   // 判断该好友是否在线
                    if (_sock != nil)
                    {
                        // 产生下线提醒包
                        NSString *userIpStr = [_sock.miniAsynSocket connectedHost];
                        NSData *userIpData = [NSKeyedArchiver archivedDataWithRootObject:userIpStr];
                        
                        NSData *reply = [self createStatusNotifyPakcet:OP_STATUS_NOTIFY_OFFLINE error:ERR_NO_ERROR userId:userIDStr userIp:userIpData];
                        NSInteger sendLength = [reply length];
                        NSMutableData *sendData = [[NSMutableData alloc] initWithBytes:&sendLength length:sizeof(sendLength)];
                        [sendData appendData:reply];
                        [_sock.miniAsynSocket writeData:sendData withTimeout:-1 tag:0];
                    }
                }
            }
        }
        [mysql disconnect];
    }
}

// 掉线处理
- (void)sendFallLinePacket:(NSNotification *)notification
{
    NSDictionary *userInfo = [notification userInfo];
    NSNumber *idNum = [userInfo objectForKey:@"idNum"];
    NSInteger id = [idNum intValue];
    NSString *idStr = [self convertQQNumToString:id];
    
    MysqlDB *mysql = [[MysqlDB alloc] init];
    [mysql connectHost:hostIp connectUser:userName connectPassword:password connectName:dbName];
    
    // 查找该用户的所有好友，并向其发其所有在线好友发送上线提醒
    NSMutableString *sqlQueryForFriends = [[NSMutableString alloc] initWithFormat:@"SELECT * FROM tbFriends WHERE UserId = '"];
    [sqlQueryForFriends appendString:idStr];
    [sqlQueryForFriends appendString:@"'"];
    NSMutableArray *buddyList = [mysql doDataQuery:sqlQueryForFriends];
    
    for (NSInteger i=0; i<[buddyList count]; ++i)
    {
        NSMutableArray *buddy = [buddyList objectAtIndex:i];
        if ([buddy count] > COLUMN_OF_FRIENDID_IN_TBFRIENDS)   // 读出的数据有问题(比如数据表的字段修改了)
        {
            NSString *buddyIdStr = [buddy objectAtIndex:COLUMN_OF_FRIENDID_IN_TBFRIENDS];
            NSInteger buddyId = [buddyIdStr intValue];
            @synchronized([MainSocketDelegate connectedSocketsQueue])
            {
                MiniSocket *_sock = [self isBuddyOnline:buddyId];   // 判断该好友是否在线
                if (_sock != nil)
                {
                    // 产生下线提醒包
                    NSString *userIpStr = [_sock.miniAsynSocket connectedHost];
                    NSData *userIpData = [NSKeyedArchiver archivedDataWithRootObject:userIpStr];
                    
                    NSData *reply = [self createStatusNotifyPakcet:OP_STATUS_NOTIFY_OFFLINE error:ERR_NO_ERROR userId:idStr userIp:userIpData];
                    NSInteger sendLength = [reply length];
                    NSMutableData *sendData = [[NSMutableData alloc] initWithBytes:&sendLength length:sizeof(sendLength)];
                    [sendData appendData:reply];
                    [_sock.miniAsynSocket writeData:sendData withTimeout:-1 tag:0];
                }
            }
        }
    }
    [mysql disconnect];
}

// 产生 上、下线提醒包
- (NSData *)createStatusNotifyPakcet:(NSInteger)status error:(NSInteger)isError userId:(NSString *)userId userIp:(NSData *)userIp
{
    STATUSNOTIFYHRD *replyHRD;
    NSInteger packetLength = 0;
    if (isError != ERR_NO_ERROR)
    {
        packetLength = sizeof(STATUSNOTIFYHRD);
        replyHRD = (STATUSNOTIFYHRD *)NewPtr(packetLength);
        
        replyHRD->type = CMD_FUN_STATUSNOTIFY;
        replyHRD->operation = status;
        replyHRD->error = isError;
        replyHRD->userid_len = 0;
        replyHRD->userip_len = 0;
    }
    else
    {
        NSData *userIdData = [NSKeyedArchiver archivedDataWithRootObject:userId];
        
        packetLength = sizeof(STATUSNOTIFYHRD) + [userIdData length] + [userIp length];
        replyHRD = (STATUSNOTIFYHRD *)NewPtr(packetLength);
        
        replyHRD->type = CMD_FUN_STATUSNOTIFY;
        replyHRD->operation = status;
        replyHRD->error = isError;
        replyHRD->userid_len = [userIdData length];
        replyHRD->userip_len = [userIp length];
        
        char *replyUserId = (char *)replyHRD + sizeof(STATUSNOTIFYHRD);
        [userIdData getBytes:replyUserId length:[userIdData length]];
        
        char *replyUserIp = (char *)replyHRD + sizeof(STATUSNOTIFYHRD) + [userIdData length];
        [userIp getBytes:replyUserIp length:[userIp length]];
    }
    NSData *reply = [[NSData alloc] initWithBytes:replyHRD length:packetLength];
    DisposePtr((char *)replyHRD);
    return reply;
}

// 判断 userId 对应的用户是否在线
- (MiniSocket *)isBuddyOnline:(NSInteger)userId
{
    @synchronized([MainSocketDelegate connectedSocketsQueue])
    {
        // 遍历 connectedSocketQueue，找到该好友的 _sock
        for (MiniSocket *_sock in [MainSocketDelegate connectedSocketsQueue]) 
        {
            if (_sock.userId == userId)
            {
                return _sock;
            }
        }
        return nil;
    }
}

// 把 NSInteger 的qq号转换为 NSString 的
- (NSString *)convertQQNumToString:(NSInteger)qqNum
{
#ifndef QQ_NUM_LEN
#define QQ_NUM_LEN 10
#endif
    NSMutableString *qqNumStr = [[NSMutableString alloc] initWithFormat:@"%ld", qqNum];
    while ([qqNumStr length] != QQ_NUM_LEN)
    {
        [qqNumStr insertString:@"0" atIndex:0];
    }
    return qqNumStr;
}

@end
